package com.gitee.candy.utils;

import com.gitee.candy.http.ThreadMdcUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.MDC;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.util.concurrent.ListenableFuture;

import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 继承线程执行器打印出具体的信息
 *
 * @author suyl
 * @date 2022-07-05
 */
public class VisibleThreadPoolTaskExecutor extends ThreadPoolTaskExecutor {

    private static final Log log = LogFactory.getLog(VisibleThreadPoolTaskExecutor.class);

    private void showThreadPoolInfo() {
        ThreadPoolExecutor threadPoolExecutor = getThreadPoolExecutor();
        log.info("线程前缀名称[" + this.getThreadNamePrefix() + "],任务数 [" + threadPoolExecutor.getTaskCount() + "], 完成任务数 [" + threadPoolExecutor.getCompletedTaskCount() + "], 活跃的线程数 [" + threadPoolExecutor.getActiveCount() + "], 当前队列中任务数量 [" + threadPoolExecutor.getQueue().size() + "]");
    }

    @Override
    public void execute(Runnable task, long startTimeout) {
        showThreadPoolInfo();
        super.execute(task, startTimeout);
    }

    @Override
    public ListenableFuture<?> submitListenable(Runnable task) {
        showThreadPoolInfo();
        return super.submitListenable(task);
    }

    @Override
    public <T> ListenableFuture<T> submitListenable(Callable<T> task) {
        showThreadPoolInfo();
        return super.submitListenable(task);
    }

    @Override
    public void execute(Runnable task) {
        showThreadPoolInfo();
        super.execute(ThreadMdcUtils.wrap(task, MDC.getCopyOfContextMap()));
    }

//    @Override
//    public <T> Future<T> submit(Runnable task, T result) {
//        showThreadPoolInfo();
//        return super.submit(ThreadMdcUtils.wrap(task, MDC.getCopyOfContextMap()), result);
//    }

    @Override
    public <T> Future<T> submit(Callable<T> task) {
        showThreadPoolInfo();
        return super.submit(ThreadMdcUtils.wrap(task, MDC.getCopyOfContextMap()));
    }

    @Override
    public Future<?> submit(Runnable task) {
        showThreadPoolInfo();
        return super.submit(ThreadMdcUtils.wrap(task, MDC.getCopyOfContextMap()));
    }

}
